const tool = {}

/**
 * LocalStorage
 */
tool.local = {
  set(table, settings) {
    let _set = JSON.stringify(settings)
    return localStorage?.setItem(table, _set)
  },
  get(table) {
    let data = localStorage?.getItem(table)
    try {
      data = JSON.parse(data)
    } catch (err) {
      return null
    }
    return data
  },
  remove(table) {
    return localStorage?.removeItem(table)
  },
  clear() {
    return localStorage?.clear()
  }
}

/**
 * SessionStorage
 */
tool.session = {
  set(table, settings) {
    let _set = JSON.stringify(settings)
    return sessionStorage?.setItem(table, _set)
  },
  get(table) {
    let data = sessionStorage?.getItem(table)
    try {
      data = JSON.parse(data)
    } catch (err) {
      return null
    }
    return data
  },
  remove(table) {
    return sessionStorage?.removeItem(table)
  },
  clear() {
    return sessionStorage?.clear()
  }
}

/**
 * CookieStorage
 */
tool.cookie = {
  set(name, value, config = {}) {
    var cfg = {
      expires: null,
      path: null,
      domain: null,
      secure: false,
      httpOnly: false,
      ...config
    }
    var cookieStr = `${name}=${escape(value)}`
    if (cfg.expires) {
      var exp = new Date()
      exp.setTime(exp.getTime() + parseInt(cfg.expires) * 1000)
      cookieStr += `;expires=${exp.toGMTString()}`
    }
    if (cfg.path) {
      cookieStr += `;path=${cfg.path}`
    }
    if (cfg.domain) {
      cookieStr += `;domain=${cfg.domain}`
    }
    document.cookie = cookieStr
  },
  get(name) {
    var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"))
    if (arr != null) {
      return unescape(arr[2])
    } else {
      return null
    }
  },
  remove(name) {
    var exp = new Date()
    exp.setTime(exp.getTime() - 1)
    document.cookie = `${name}=;expires=${exp.toGMTString()}`
  }
}

/* Fullscreen */
tool.screen = (element) => {
  let isFull = !!(document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement)
  if (isFull) {
    if (document.exitFullscreen) {
      document.exitFullscreen()
    } else if (document.msExitFullscreen) {
      document.msExitFullscreen()
    } else if (document.mozCancelFullScreen) {
      document.mozCancelFullScreen()
    } else if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen()
    }
  } else {
    if (element.requestFullscreen) {
      element.requestFullscreen()
    } else if (element.msRequestFullscreen) {
      element.msRequestFullscreen()
    } else if (element.mozRequestFullScreen) {
      element.mozRequestFullScreen()
    } else if (element.webkitRequestFullscreen) {
      element.webkitRequestFullscreen()
    }
  }
}
/* 复制对象 */
tool.objCopy = (obj) => {
  if (obj === undefined) {
    return undefined
  }
  return JSON.parse(JSON.stringify(obj))
}

tool.generateId = function () {
  return Math.floor(Math.random() * 100000 + Math.random() * 20000 + Math.random() * 5000)
}

tool.viewImage = function (path, defaultStorage = "LOCAL") {
  let mode = tool.local.get("site_storage_mode") ? tool.local.get("site_storage_mode").toUpperCase() : defaultStorage
  return uploadConfig.storage[mode] + path
}

/* 日期格式化 */
tool.dateFormat = (date, fmt = "yyyy-MM-dd hh:mm:ss", isDefault = "-") => {
  if (date.toString().length == 10) {
    date = date * 1000
  }
  date = new Date(date)

  if (date.valueOf() < 1) {
    return isDefault
  }
  let o = {
    "M+": date.getMonth() + 1, //月份
    "d+": date.getDate(), //日
    "h+": date.getHours(), //小时
    "m+": date.getMinutes(), //分
    "s+": date.getSeconds(), //秒
    "q+": Math.floor((date.getMonth() + 3) / 3), //季度
    S: date.getMilliseconds() //毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length))
  }
  for (let k in o) {
    if (new RegExp("(" + k + ")").test(fmt)) {
      fmt = fmt.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length))
    }
  }
  return fmt
}

/* 千分符 */
tool.groupSeparator = (num) => {
  num = num + ""
  if (!num.includes(".")) {
    num += "."
  }
  return num
    .replace(/(\d)(?=(\d{3})+\.)/g, function ($0, $1) {
      return $1 + ","
    })
    .replace(/\.$/, "")
}
tool.download = (res, downName = "") => {
  const aLink = document.createElement("a")
  let fileName = downName
  let blob = res // 第三方请求返回blob对象

  //通过后端接口返回
  if (res.headers && res.data) {
    blob = new Blob([res.data], { type: res.headers["content-type"].replace(";charset=utf8", "") })
    if (!downName) {
      const contentDisposition = decodeURI(res.headers["content-disposition"])
      const result = contentDisposition.match(/filename\*=utf-8\'\'(.+)/gi)
      fileName = result[0].replace(/filename\*=utf-8\'\'/gi, "")
    }
  }

  aLink.href = URL.createObjectURL(blob)
  // 设置下载文件名称
  aLink.setAttribute("download", fileName)
  document.body.appendChild(aLink)
  aLink.click()
  document.body.removeChild(aLink)
  URL.revokeObjectURL(aLink.href)
}

/**
 * 下载文件
 * @param {string} url 文件路径
 * @param {string} fileName 文件名称
 * @param {string} suffix 后缀名称
 */
tool.downloadFile = (url, fileName, suffix) => {
  const xhr = new XMLHttpRequest()
  xhr.open("GET", url, true)
  xhr.responseType = "blob" // 通过文件下载url拿到对应的blob对象
  xhr.onload = () => {
    if (xhr.status === 200) {
      let link = document.createElement("a")
      let body = document.querySelector("body")
      link.href = window.URL.createObjectURL(xhr.response)
      console.log("xhr.response",xhr.response)
      link.download = `${fileName}.${suffix}`
      link.click()
      // body.removeChild(link);
      window.URL.revokeObjectURL(link.href)
    }
  }
  xhr.send()
}

/**
 * 对象转url参数
 * @param {*} data
 * @param {*} isPrefix
 */
tool.httpBuild = (data, isPrefix = false) => {
  let prefix = isPrefix ? "?" : ""
  let _result = []
  for (let key in data) {
    let value = data[key]
    // 去掉为空的参数
    if (["", undefined, null].includes(value)) {
      continue
    }
    if (value.constructor === Array) {
      value.forEach((_value) => {
        _result.push(encodeURIComponent(key) + "[]=" + encodeURIComponent(_value))
      })
    } else {
      _result.push(encodeURIComponent(key) + "=" + encodeURIComponent(value))
    }
  }

  return _result.length ? prefix + _result.join("&") : ""
}

tool.getRequestParams = (url) => {
  const theRequest = new Object()
  if (url.indexOf("?") != -1) {
    const params = url.split("?")[1].split("&")
    for (let i = 0; i < params.length; i++) {
      const param = params[i].split("=")
      theRequest[param[0]] = decodeURIComponent(param[1])
    }
  }
  return theRequest
}

tool.attachUrl = (path, defaultStorage = "LOCAL") => {
  return uploadConfig.storage[defaultStorage] + path
}

/**
 * 获取token
 */
tool.getToken = () => {
  return tool.local.get("token")
}
/**
 * 节流
 */
tool.throttle = (fn, delay = 600) => {
  let flag = true
  return function () {
    if (!flag) return
    flag = false
    setTimeout(() => {
      fn.apply(this, arguments)
      flag = true
    }, delay)
  }
}
/**
 * 转Unix时间戳
 */

tool.toUnixTime = (date) => {
  return Math.floor(new Date(date).getTime() / 1000)
}

tool.arrSum = (arr) => {
  let sum = 0
  arr.map((item) => (sum += item))
  return sum
}
/**
 * @description 将获取的数据对象映射到数组中
 * @param {object} array   表单内容名
 * @param {object} current 当前获取的映射数据
 * @param {object} mapping 获取的数据
 * */
tool.mappingData = (array, current, mapping) => {
  array.forEach((item) => {
    if (mapping[item.field]) {
      return (current[item.field] = mapping[item.field])
    } else {
      return (current[item.field] = " ")
    }
  })
}

/**
 * @description 添加数组对象去重
 * @param {array} array 需要添加进去的数组
 * @param {object} newObject 需要添加进去的对象
 * @param {string} field 筛选字段
 * */
tool.upsertArrayElement = (array, newObject, field) => {
  const objectId = newObject[field]
  const index = array.findIndex((obj) => obj[field] === objectId)
  if (index !== -1) {
    // 如果找到了对象ID，则替换
    array[index] = newObject
  } else {
    // 如果没有找到，则添加到数组中
    array.push(newObject)
  }
}
/**
 * @description 判断是否为普通对象
 * @param {value} obj 需要添加进去的数组
 * */
tool.isObject = (obj) => {
  return typeof obj === "object" && obj !== null && !Array.isArray(obj)
}
/**
 * @description 定义一个递归函数，用于构建菜单分类选择树形结构
 * @description 筛选条件 conditionFn = node => node.is_show,
 * */
tool.buildMenuTreeCate = (nodes, renameFn = (node) => node.menu_name, setId = (node) => node.id) => {
  return (
    nodes
      // .filter(conditionFn) // 先筛选出满足条件的节点
      .map((node) => ({
        // ...node,
        // 自定义菜单项名称
        label: renameFn(node),
        value: setId(node),
        // 如果当前节点有children属性且非空，则递归处理其子节点，同时传递筛选和自定义名称函数
        children: node.children && node.children.length > 0 ? tool.buildMenuTreeCate(node.children, renameFn, setId) : []
      }))
  )
}
/**
 * @description 定义一个递归函数，用于构建菜单结构
 * @description 筛选条件 conditionFn = node => node.is_show,
 * */
tool.buildMenuTree = (nodes, renameFn = (node) => node.title, rePathFn = (node) => node.path,reIcon = node => node.icon) => {
  return (
    nodes
      // .filter(conditionFn) // 先筛选出满足条件的节点
      .map((node) => ({
        // ...node,
        // 自定义菜单项名称
        label: renameFn(node),
        path: rePathFn(node),
        icon: reIcon(node),
        // 如果当前节点有children属性且非空，则递归处理其子节点，同时传递筛选和自定义名称函数
        children: node.children && node.children.length > 0 ? tool.buildMenuTree(node.children, renameFn, rePathFn,reIcon) : []
      }))
  )
}

export default tool
